library(fpca)
Loading required package: sm
package ‘sm’ was built under R version 3.4.4Package 'sm', version 2.2-5.6: type help(sm) for summary information
Loading required package: splines
# options
# display as decimal, not scientific notation
options(scipen = 999)
# data for 2013 - 2016
county_poverty <- read.csv(file = 'county_poverty_hist.csv', header = TRUE, sep = ',')
county_poverty$geo_sumlevel <- gsub('[[:punct:]]\\s', '', str_extract(county_poverty$geo_name, '\\,\\s[A-Z]{2}'))
county_poverty$geo_name <- gsub('\\,\\s[A-Z]{2}', '', county_poverty$geo_name)
county_poverty <- county_poverty[-3]
# naming scheme:
# pYEAR = number of people in poverty, for the given year
# prYEAR = poverty rate, for the given year
# popYEAR = total population, for the given year
names(county_poverty) <- c('county', 'state',
'p2013', 'p2014', 'p2015',
'pr2013', 'pr2014', 'pr2015',
'pr2016', 'p2016', 'pop2013',
'pop2014', 'pop2015', 'pop2016')
county_poverty <- county_poverty %>%
na.omit() %>%
select(sort(current_vars()))
# remove Puerto Rico
county_poverty <- county_poverty %>%
filter(state != 'PR')
county_poverty <- county_poverty %>%
select(sort(current_vars()))
# economic/unemployment data
# https://apps.bea.gov/regional/
ec <- read.csv('CAINC4__ALL_STATES_1969_2017.csv', header = TRUE, sep = ',')
ec <- ec[, c('GeoFIPS', 'GeoName', 'Description', 'X2013', 'X2014', 'X2015', 'X2016')]
ec$Description <- gsub('[[:punct:]]', '', ec$Description) %>%
trimws()
# keep 'Per capita personal income (dollars) 4/', 'Total employment', 'Farm proprietors' income', 'Nonfarm proprietors' income'
# clean data
ec <- ec %>%
filter(ec$Description == 'Per capita personal income dollars 4' |
ec$Description == 'Total employment' |
ec$Description == 'Farm proprietors income' |
ec$Description == 'Nonfarm proprietors income')
ec$Description[ec$Description == 'Per capita personal income dollars 4'] <- 'income'
ec$Description[ec$Description == 'Total employment'] <- 'empl_count'
ec$Description[ec$Description == 'Farm proprietors income'] <- 'farm_income'
ec$Description[ec$Description == 'Nonfarm proprietors income'] <- 'nonfarm_income'
ec <- dcast(melt(ec,
id.vars = c('GeoFIPS', 'GeoName', 'Description'),
measure.vars = c('X2013', 'X2014', 'X2015', 'X2016')),
GeoFIPS + GeoName + variable ~ Description) %>%
mutate(variable = gsub('X', '', variable))
attributes are not identical across measure variables; they will be dropped
ec[, 1:2] <- lapply(ec[, 1:2], as.character)
ec[, c(1, 3:7)] <- lapply(ec[, c(1, 3:7)], as.numeric)
NAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercion
ec$p_farm_income <- ec$farm_income / ec$nonfarm_income
ec[is.na(ec)] <- 0
# combine economic data with land area
area <- read_excel('LND01.xls')[,c(2,4)]
Error in read_fun(path = path, sheet = sheet, limits = limits, shim = shim, :
path[1]="LND01.xls": No such file or directory
# create tall data set
cp1 <- gather(county_poverty[c(1:5, 14)], year, poverty_count, p2013:p2016, factor_key = TRUE) %>%
mutate(year = str_extract(year, '\\d{4}'))
cp2 <- gather(county_poverty[c(1, 6:9, 14)], year, total_count, pop2013:pop2016, factor_key = TRUE) %>%
mutate(year = str_extract(year, '\\d{4}'))
cp <- merge(cp1, cp2, by = c('county', 'state', 'year')) %>%
mutate(poverty_rate = poverty_count / total_count,
year = year %>% as.numeric())
cp$county <- gsub('\\sCounty', '', cp$county)
cp$county <- gsub('\\sParish', '', cp$county)
cp$county <- gsub('\\scity', '\\sCity', cp$county)
cp$county <- gsub('[[:punct:]]', '', cp$county)
cp$county <- cp$county %>%
trimws()
# county data
county_ec <- ec[!(ec$GeoFIPS %% 1000 == 0), ]
county_ec <- subset(county_ec, select = -c(GeoFIPS))
county_ec$state <- gsub('[[:punct:]]\\s', '', str_extract(county_ec$GeoName, '\\,\\s[A-Z]{2}'))
county_ec$GeoName <- gsub('\\,\\s[A-Z]{2}', '', county_ec$GeoName)
names(county_ec) <- c('county', 'year', 'empl_count', 'farm_income', 'income', 'nonfarm_income', 'p_farm_income', 'area', 'state')
county_ec$county <- gsub('[[:punct:]]', '', county_ec$county)
county_ec$county <- gsub('\\sIndependent\\sCity', '\\sCity', county_ec$county)
county_ec$county <- gsub('\\sStaunton\\sWaynesboro', '', county_ec$county)
# manual fix for counties with area = 0
# scrape areas from Wikipedia, as Census data was inadequate
zeroarea <- county_ec[which(county_ec$area == 0), -c(2:7)] %>%
unique()
zeroarea$wiki_link <- gsub(' City and Borough', '', zeroarea$county)
zeroarea$wiki_link <- gsub(' Municipality', '', zeroarea$wiki_link)
zeroarea$wiki_link <- gsub('[A-Z]{2}', '',
paste('https://en.wikipedia.org/wiki/',
gsub('\\s', '_', zeroarea$wiki_link), ',_',
gsub('AK', 'Alaska', zeroarea$state),
gsub('CO', 'Colorado', zeroarea$state),
sep = ''))
for(i in 1:nrow(zeroarea)) {
zeroarea$area[i] <- gsub(',', '', read_html(zeroarea$wiki_link[i]) %>%
html_nodes(xpath = '//th[contains(., "Area")]//parent::tr/following-sibling::tr[1]/td') %>%
html_text() %>%
str_extract('[\\d\\.,]+'))[1] %>%
as.numeric()
county_ec$area[which(county_ec$county == zeroarea$county[i])] <- zeroarea$area[which(zeroarea$county == zeroarea$county[i])]
}
county_data <- merge(cp, county_ec, by = c('county', 'state', 'year')) %>%
mutate(empl_rate = empl_count / total_count,
pop_dens = total_count / area)
# 'county_data' to wide
st <- list()
for (i in 2013:2016) {
df <- county_data %>%
filter(year == i)
df <- df[, -3]
df_names <- names(df)
df_names[3] <- paste('p', i %>% as.character(), sep = '')
df_names[4] <- paste('pop', i %>% as.character(), sep = '')
df_names[5] <- paste('pr', i %>% as.character(), sep = '')
df_names[6] <- paste('ec', i %>% as.character(), sep = '')
df_names[7] <- paste('f_inc', i %>% as.character(), sep = '')
df_names[8] <- paste('inc', i %>% as.character(), sep = '')
df_names[9] <- paste('nf_inc', i %>% as.character(), sep = '')
df_names[10] <- paste('pf_inc', i %>% as.character(), sep = '')
df_names[12] <- paste('er', i %>% as.character(), sep = '')
df_names[13] <- paste('pop_dens', i %>% as.character(), sep = '')
names(df) <- df_names
st[[i - 2012]] <- df
}
county_data_wide <- merge(st[[1]], st[[2]], by = c('state', 'county', 'area'))
county_data_wide <- merge(county_data_wide, st[[3]], by = c('state', 'county', 'area'))
county_data_wide <- merge(county_data_wide, st[[4]], by = c('state', 'county', 'area'))
# data set of poverty, by state
state_poverty <- table(county_data_wide$state) %>%
data.frame()
names(state_poverty) <- c('state', 'n_counties')
# 51 = number of states, including Washington D.C.
# create a data table of summary stats per state
sp <- list()
for(i in 1:51) {
state_stats <- data.frame(summary(county_data_wide[which(county_data_wide$state == state_poverty$state[i]), ]))[13:258, 2:3] %>%
mutate(stat = gsub('\\s*\\:', '', str_extract(Freq, '.*\\:')),
Freq = gsub(':', '', str_extract(Freq, '\\:.+')) %>% as.numeric()) %>%
reshape(idvar = 'Var2', timevar = 'stat', direction = 'wide') %>%
mutate(Year = str_extract(Var2, '\\d{4}'),
Var2 = str_extract(Var2, '[a-z_]{1,7}'),
state = state_poverty$state[i])
sp[[i]] <- state_stats
}
# clean data, rename variables and reorganize column order
state_poverty <- merge(state_poverty, do.call(rbind, sp), by = 'state') %>%
select(sort(current_vars()))
state_poverty <- state_poverty[, c(8, 10, 7, 9, 1:6)]
state_poverty$Var2[state_poverty$Var2 == 'p'] <- 'poverty_count'
state_poverty$Var2[state_poverty$Var2 == 'pr'] <- 'poverty_rate'
state_poverty$Var2[state_poverty$Var2 == 'pop'] <- 'total_count'
state_poverty$Var2[state_poverty$Var2 == 'ec'] <- 'empl_count'
state_poverty$Var2[state_poverty$Var2 == 'f_inc'] <- 'farm_income'
state_poverty$Var2[state_poverty$Var2 == 'inc'] <- 'income'
state_poverty$Var2[state_poverty$Var2 == 'f_inc'] <- 'farm_income'
state_poverty$Var2[state_poverty$Var2 == 'nf_inc'] <- 'nonfarm_income'
state_poverty$Var2[state_poverty$Var2 == 'pf_inc'] <- 'p_farm_income'
state_poverty$Var2[state_poverty$Var2 == 'er'] <- 'empl_rate'
state_poverty$Var2[state_poverty$Var2 == 'area'] <- 'area'
state_poverty$Var2[state_poverty$Var2 == 'pop_den'] <- 'pop_dens'
names(state_poverty) <- c('state', 'year', 'n_counties', 'countystat', '1st_quantile', '3rd_quantile', 'max', 'mean', 'median', 'minimum')
# replace NAs for 'year'
for(i in 1:nrow(state_poverty)) {
if(state_poverty$year[i] %>% is.na) {
state_poverty$year[i] <- state_poverty$year[i + 1]
}
}
# create variables measuring the standard deviation and variance of county stats, per year
state_variance <- c()
state_sd <- c()
for(i in 1:nrow(state_poverty)) {
state_variance[i] <- county_data %>%
filter(state == state_poverty$state[i] & year == state_poverty$year[i]) %>%
select(state_poverty$countystat[i]) %>%
var()
state_sd[i] <- sapply(county_data %>% filter(state == state_poverty$state[i] & year == state_poverty$year[i]) %>% select(state_poverty$countystat[i]), sd)[[1]][1]
}
state_poverty$var <- state_variance
state_poverty$sd <- state_sd
state_poverty[is.na(state_poverty)] <- 0
# merge state stats with statistics on total state population ('state_ec'), total state poverty count, and overall state poverty rate (aggregating 'cp')
# change 'state_ec' names from full words to 2-letter abbreviations
for(i in 1:nrow(state_ec)) {
if(state_ec$state[i] == 'District of Columbia') {
state_ec$state[i] <- 'DC'
} else {
state_ec$state[i] <- state.abb[grep(state_ec$state[i], state.name)]
}
}
number of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement length
state_ec <- merge(state_ec,
merge(aggregate(poverty_count ~ state + year, cp, sum),
aggregate(total_count ~ state + year, cp, sum),
by = c('state', 'year')),
by = c('state', 'year')) %>%
mutate(poverty_rate = poverty_count / total_count,
empl_rate = empl_count / total_count)
state_ec <- merge(state_poverty, state_ec, by = c('state', 'year'))
# rename state-wide variables for clarity
names(state_ec) <- c('state', 'year', 'n_counties', 'countystat', '1st_quantile', '3rd_quantile', 'max', 'mean', 'median', 'minimum', 'var', 'sd', 'state_empl_count', 'state_farm_income', 'state_avg_income', 'state_nonfarm_income', 'state_p_farm_income', 'state_area', 'state_poverty_count', 'state_total_count', 'state_poverty_rate', 'state_empl_rate')
row.names(state_data) <- state_data$state
non-unique values when setting 'row.names': ‘AK’, ‘AL’, ‘AR’, ‘AZ’, ‘CA’, ‘CO’, ‘CT’, ‘DC’, ‘DE’, ‘FL’, ‘GA’, ‘HI’, ‘IA’, ‘ID’, ‘IL’, ‘IN’, ‘KS’, ‘KY’, ‘LA’, ‘MA’, ‘MD’, ‘ME’, ‘MI’, ‘MN’, ‘MO’, ‘MS’, ‘MT’, ‘NC’, ‘ND’, ‘NE’, ‘NH’, ‘NJ’, ‘NM’, ‘NV’, ‘NY’, ‘OH’, ‘OK’, ‘OR’, ‘PA’, ‘RI’, ‘SC’, ‘SD’, ‘TN’, ‘TX’, ‘UT’, ‘VA’, ‘VT’, ‘WA’, ‘WI’, ‘WV’, ‘WY’Error in `row.names<-.data.frame`(`*tmp*`, value = c(1L, 1L, 1L, 1L, 1L, :
duplicate 'row.names' are not allowed
lm(state_vcrime_rate ~ state + year + var,
data = state_data %>% filter(countystat == 'poverty_rate')) %>%
msummary()
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.16600898 0.02987540 -5.557 0.000000121172815565 ***
stateAL -0.00256400 0.00016705 -15.349 < 0.0000000000000002 ***
stateAR -0.00185904 0.00020580 -9.033 0.000000000000000738 ***
stateAZ -0.00282847 0.00017330 -16.321 < 0.0000000000000002 ***
stateCA -0.00280151 0.00019896 -14.081 < 0.0000000000000002 ***
stateCO -0.00389012 0.00017447 -22.297 < 0.0000000000000002 ***
stateCT -0.00434224 0.00032718 -13.272 < 0.0000000000000002 ***
stateDC 0.00709309 0.00037155 19.090 < 0.0000000000000002 ***
stateDE -0.00146553 0.00036157 -4.053 0.000080609750724398 ***
stateFL -0.00233992 0.00020156 -11.609 < 0.0000000000000002 ***
stateGA -0.00348890 0.00018308 -19.056 < 0.0000000000000002 ***
stateHI -0.00444839 0.00020108 -22.123 < 0.0000000000000002 ***
stateIA -0.00396951 0.00029232 -13.579 < 0.0000000000000002 ***
stateID -0.00478225 0.00022306 -21.440 < 0.0000000000000002 ***
stateIL -0.00296354 0.00022463 -13.193 < 0.0000000000000002 ***
stateIN -0.00304924 0.00025604 -11.909 < 0.0000000000000002 ***
stateKS -0.00313147 0.00024636 -12.711 < 0.0000000000000002 ***
stateKY -0.00520906 0.00018352 -28.384 < 0.0000000000000002 ***
stateLA -0.00191695 0.00017918 -10.699 < 0.0000000000000002 ***
stateMA -0.00281371 0.00026630 -10.566 < 0.0000000000000002 ***
stateMD -0.00233531 0.00018345 -12.730 < 0.0000000000000002 ***
stateME -0.00553603 0.00030059 -18.417 < 0.0000000000000002 ***
stateMI -0.00248043 0.00024486 -10.130 < 0.0000000000000002 ***
stateMN -0.00444102 0.00028297 -15.694 < 0.0000000000000002 ***
stateMO -0.00219310 0.00020779 -10.555 < 0.0000000000000002 ***
stateMS -0.00474653 0.00021443 -22.135 < 0.0000000000000002 ***
stateMT -0.00375591 0.00017411 -21.572 < 0.0000000000000002 ***
stateNC -0.00346685 0.00020981 -16.524 < 0.0000000000000002 ***
stateND -0.00459135 0.00017237 -26.637 < 0.0000000000000002 ***
stateNE -0.00403924 0.00026724 -15.115 < 0.0000000000000002 ***
stateNH -0.00463935 0.00033665 -13.781 < 0.0000000000000002 ***
stateNJ -0.00434025 0.00023178 -18.725 < 0.0000000000000002 ***
stateNM -0.00078217 0.00016708 -4.681 0.000006292790458193 ***
stateNV -0.00010532 0.00026927 -0.391 0.69625
stateNY -0.00301692 0.00025059 -12.039 < 0.0000000000000002 ***
stateOH -0.00400565 0.00022659 -17.678 < 0.0000000000000002 ***
stateOK -0.00250750 0.00022000 -11.398 < 0.0000000000000002 ***
stateOR -0.00418656 0.00028998 -14.437 < 0.0000000000000002 ***
statePA -0.00356266 0.00029106 -12.240 < 0.0000000000000002 ***
stateRI -0.00448894 0.00024850 -18.064 < 0.0000000000000002 ***
stateSC -0.00183783 0.00019820 -9.273 < 0.0000000000000002 ***
stateSD -0.00445006 0.00053285 -8.351 0.000000000000040245 ***
stateTN -0.00062988 0.00023868 -2.639 0.00919 **
stateTX -0.00292348 0.00016753 -17.450 < 0.0000000000000002 ***
stateUT -0.00470278 0.00019850 -23.692 < 0.0000000000000002 ***
stateVA -0.00509680 0.00017780 -28.666 < 0.0000000000000002 ***
stateVT -0.00553576 0.00032929 -16.811 < 0.0000000000000002 ***
stateWA -0.00399023 0.00023101 -17.273 < 0.0000000000000002 ***
stateWI -0.00389852 0.00026240 -14.857 < 0.0000000000000002 ***
stateWV -0.00362839 0.00022946 -15.812 < 0.0000000000000002 ***
stateWY -0.00481323 0.00021980 -21.898 < 0.0000000000000002 ***
year 0.00008573 0.00001484 5.775 0.000000042337838656 ***
var 0.17040076 0.08546137 1.994 0.04796 *
Residual standard error: 0.0002361 on 151 degrees of freedom
Multiple R-squared: 0.9892, Adjusted R-squared: 0.9855
F-statistic: 267.2 on 52 and 151 DF, p-value: < 0.00000000000000022
lm(state_vcrime_rate ~ state + year + var,
data = state_data %>% filter(countystat == 'pop_dens')) %>%
msummary()
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.1827872107075 0.0303324801240 -6.026 0.00000001231859 ***
stateAL -0.0025493182041 0.0001668002380 -15.284 < 0.0000000000000002 ***
stateAR -0.0020979024549 0.0001667972137 -12.578 < 0.0000000000000002 ***
stateAZ -0.0029184502459 0.0001668019413 -17.497 < 0.0000000000000002 ***
stateCA -0.0028741075426 0.0001807304400 -15.903 < 0.0000000000000002 ***
stateCO -0.0039084943962 0.0001715695923 -22.781 < 0.0000000000000002 ***
stateCT -0.0048580721635 0.0001682370770 -28.876 < 0.0000000000000002 ***
stateDC 0.0064310304350 0.0001667963389 38.556 < 0.0000000000000002 ***
stateDE -0.0020356735023 0.0001701650369 -11.963 < 0.0000000000000002 ***
stateFL -0.0025321098431 0.0001675660907 -15.111 < 0.0000000000000002 ***
stateGA -0.0033014425537 0.0001677913113 -19.676 < 0.0000000000000002 ***
stateHI -0.0046580265936 0.0001669320526 -27.904 < 0.0000000000000002 ***
stateIA -0.0044460794373 0.0001667988342 -26.655 < 0.0000000000000002 ***
stateID -0.0050759510004 0.0001667974490 -30.432 < 0.0000000000000002 ***
stateIL -0.0032158361676 0.0001683788492 -19.099 < 0.0000000000000002 ***
stateIN -0.0034169488730 0.0001670618208 -20.453 < 0.0000000000000002 ***
stateKS -0.0034863016927 0.0001668255622 -20.898 < 0.0000000000000002 ***
stateKY -0.0050451230154 0.0001668970430 -30.229 < 0.0000000000000002 ***
stateLA -0.0017758906576 0.0001668862211 -10.641 < 0.0000000000000002 ***
stateMA -0.0026129656517 0.0003419663795 -7.641 0.00000000000231 ***
stateMD -0.0020062377339 0.0002870198856 -6.990 0.00000000008269 ***
stateME -0.0060332541499 0.0001667973205 -36.171 < 0.0000000000000002 ***
stateMI -0.0028024760819 0.0001676667651 -16.715 < 0.0000000000000002 ***
stateMN -0.0048562286115 0.0001679446942 -28.916 < 0.0000000000000002 ***
stateMO -0.0023798550820 0.0001693199909 -14.055 < 0.0000000000000002 ***
stateMS -0.0044775551126 0.0001667965858 -26.844 < 0.0000000000000002 ***
stateMT -0.0038547370663 0.0001667963284 -23.110 < 0.0000000000000002 ***
stateNC -0.0037039233242 0.0001669848897 -22.181 < 0.0000000000000002 ***
stateND -0.0045058887798 0.0001667963239 -27.014 < 0.0000000000000002 ***
stateNE -0.0044474679715 0.0001668400463 -26.657 < 0.0000000000000002 ***
stateNH -0.0052165157168 0.0001668195873 -31.270 < 0.0000000000000002 ***
stateNJ -0.0029459452911 0.0008497418100 -3.467 0.000686 ***
stateNM -0.0007657653601 0.0001668009087 -4.591 0.00000922818479 ***
stateNV -0.0005257684625 0.0001667967761 -3.152 0.001955 **
stateNY 0.0112834420635 0.0071310049495 1.582 0.115672
stateOH -0.0042770322678 0.0001676181947 -25.517 < 0.0000000000000002 ***
stateOK -0.0027859216144 0.0001668337819 -16.699 < 0.0000000000000002 ***
stateOR -0.0046375660160 0.0001671314123 -27.748 < 0.0000000000000002 ***
statePA -0.0035689816481 0.0002824186807 -12.637 < 0.0000000000000002 ***
stateRI -0.0047882652724 0.0001700080362 -28.165 < 0.0000000000000002 ***
stateSC -0.0020469628469 0.0001668071027 -12.271 < 0.0000000000000002 ***
stateSD -0.0034410995171 0.0001667963070 -20.631 < 0.0000000000000002 ***
stateTN -0.0009597260154 0.0001668712505 -5.751 0.00000004759584 ***
stateTX -0.0029277776899 0.0001671974513 -17.511 < 0.0000000000000002 ***
stateUT -0.0048991442243 0.0001670196539 -29.333 < 0.0000000000000002 ***
stateVA -0.0046485052382 0.0003234171580 -14.373 < 0.0000000000000002 ***
stateVT -0.0061011334634 0.0001667965308 -36.578 < 0.0000000000000002 ***
stateWA -0.0042988167742 0.0001668642171 -25.762 < 0.0000000000000002 ***
stateWI -0.0042972375386 0.0001668136639 -25.761 < 0.0000000000000002 ***
stateWV -0.0039400637857 0.0001667998460 -23.622 < 0.0000000000000002 ***
stateWY -0.0050985128235 0.0001667963351 -30.567 < 0.0000000000000002 ***
year 0.0000943869796 0.0000150569724 6.269 0.00000000362896 ***
var -0.0000000002637 0.0000000001281 -2.058 0.041290 *
Residual standard error: 0.0002359 on 151 degrees of freedom
Multiple R-squared: 0.9893, Adjusted R-squared: 0.9856
F-statistic: 267.6 on 52 and 151 DF, p-value: < 0.00000000000000022
lm(state_vcrime_rate ~ state + year + mean,
data = state_data %>% filter(countystat == 'p_farm_income')) %>%
msummary()
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.12103252 0.03431532 -3.527 0.000557 ***
stateAL -0.00244393 0.00016927 -14.438 < 0.0000000000000002 ***
stateAR -0.00197214 0.00017094 -11.537 < 0.0000000000000002 ***
stateAZ -0.00289953 0.00016505 -17.568 < 0.0000000000000002 ***
stateCA -0.00294148 0.00016706 -17.607 < 0.0000000000000002 ***
stateCO -0.00393034 0.00016628 -23.636 < 0.0000000000000002 ***
stateCT -0.00490279 0.00016487 -29.738 < 0.0000000000000002 ***
stateDC 0.00643088 0.00016487 39.007 < 0.0000000000000002 ***
stateDE -0.00206329 0.00016553 -12.465 < 0.0000000000000002 ***
stateFL -0.00249554 0.00016672 -14.969 < 0.0000000000000002 ***
stateGA -0.00324939 0.00016792 -19.351 < 0.0000000000000002 ***
stateHI -0.00467270 0.00016487 -28.343 < 0.0000000000000002 ***
stateIA -0.00425524 0.00017857 -23.830 < 0.0000000000000002 ***
stateID -0.00487300 0.00018018 -27.046 < 0.0000000000000002 ***
stateIL -0.00314827 0.00016987 -18.534 < 0.0000000000000002 ***
stateIN -0.00335816 0.00016720 -20.085 < 0.0000000000000002 ***
stateKS -0.00327491 0.00018218 -17.976 < 0.0000000000000002 ***
stateKY -0.00500224 0.00016602 -30.131 < 0.0000000000000002 ***
stateLA -0.00173208 0.00016603 -10.433 < 0.0000000000000002 ***
stateMA -0.00322817 0.00016487 -19.581 < 0.0000000000000002 ***
stateMD -0.00245627 0.00016523 -14.866 < 0.0000000000000002 ***
stateME -0.00602590 0.00016489 -36.544 < 0.0000000000000002 ***
stateMI -0.00282840 0.00016490 -17.152 < 0.0000000000000002 ***
stateMN -0.00477015 0.00017090 -27.913 < 0.0000000000000002 ***
stateMO -0.00236022 0.00016728 -14.109 < 0.0000000000000002 ***
stateMS -0.00443108 0.00016572 -26.739 < 0.0000000000000002 ***
stateMT -0.00367647 0.00017663 -20.814 < 0.0000000000000002 ***
stateNC -0.00364337 0.00016712 -21.801 < 0.0000000000000002 ***
stateND -0.00436628 0.00017217 -25.360 < 0.0000000000000002 ***
stateNE -0.00386418 0.00026730 -14.456 < 0.0000000000000002 ***
stateNH -0.00522206 0.00016487 -31.675 < 0.0000000000000002 ***
stateNJ -0.00465974 0.00016487 -28.264 < 0.0000000000000002 ***
stateNM -0.00066467 0.00016894 -3.934 0.000127 ***
stateNV -0.00055989 0.00016529 -3.387 0.000900 ***
stateNY -0.00336834 0.00016504 -20.409 < 0.0000000000000002 ***
stateOH -0.00429453 0.00016497 -26.032 < 0.0000000000000002 ***
stateOK -0.00266827 0.00017076 -15.626 < 0.0000000000000002 ***
stateOR -0.00457832 0.00016737 -27.355 < 0.0000000000000002 ***
statePA -0.00402305 0.00016495 -24.389 < 0.0000000000000002 ***
stateRI -0.00485617 0.00016487 -29.455 < 0.0000000000000002 ***
stateSC -0.00203865 0.00016492 -12.361 < 0.0000000000000002 ***
stateSD -0.00303679 0.00021883 -13.877 < 0.0000000000000002 ***
stateTN -0.00096544 0.00016487 -5.856 0.0000000286 ***
stateTX -0.00284826 0.00016892 -16.862 < 0.0000000000000002 ***
stateUT -0.00480114 0.00016994 -28.253 < 0.0000000000000002 ***
stateVA -0.00520559 0.00016493 -31.562 < 0.0000000000000002 ***
stateVT -0.00607852 0.00016507 -36.824 < 0.0000000000000002 ***
stateWA -0.00424245 0.00016654 -25.474 < 0.0000000000000002 ***
stateWI -0.00425670 0.00016566 -25.696 < 0.0000000000000002 ***
stateWV -0.00394624 0.00016487 -23.935 < 0.0000000000000002 ***
stateWY -0.00507286 0.00016511 -30.723 < 0.0000000000000002 ***
year 0.00006373 0.00001703 3.741 0.000259 ***
mean -0.00020643 0.00007347 -2.810 0.005616 **
Residual standard error: 0.0002332 on 151 degrees of freedom
Multiple R-squared: 0.9895, Adjusted R-squared: 0.9859
F-statistic: 274 on 52 and 151 DF, p-value: < 0.00000000000000022
lm(state_vcrime_rate ~ state + year + var,
data = state_data %>% filter(countystat == 'empl_rate')) %>%
msummary()
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.16584128 0.03046629 -5.443 0.00000020690236819 ***
stateAL -0.00232649 0.00028211 -8.247 0.00000000000007374 ***
stateAR -0.00187305 0.00028276 -6.624 0.00000000057725935 ***
stateAZ -0.00269917 0.00027963 -9.653 < 0.0000000000000002 ***
stateCA -0.00281504 0.00026403 -10.662 < 0.0000000000000002 ***
stateCO -0.00383766 0.00022849 -16.796 < 0.0000000000000002 ***
stateCT -0.00467380 0.00028559 -16.365 < 0.0000000000000002 ***
stateDC 0.00668593 0.00030639 21.822 < 0.0000000000000002 ***
stateDE -0.00187060 0.00028960 -6.459 0.00000000136363296 ***
stateFL -0.00235305 0.00027167 -8.662 0.00000000000000661 ***
stateGA -0.00318462 0.00022905 -13.903 < 0.0000000000000002 ***
stateHI -0.00442819 0.00029723 -14.898 < 0.0000000000000002 ***
stateIA -0.00422026 0.00028415 -14.852 < 0.0000000000000002 ***
stateID -0.00520768 0.00021352 -24.390 < 0.0000000000000002 ***
stateIL -0.00304324 0.00027795 -10.949 < 0.0000000000000002 ***
stateIN -0.00322055 0.00027460 -11.728 < 0.0000000000000002 ***
stateKS -0.00328264 0.00027010 -12.153 < 0.0000000000000002 ***
stateKY -0.00485795 0.00026157 -18.572 < 0.0000000000000002 ***
stateLA -0.00160218 0.00025089 -6.386 0.00000000199158404 ***
stateMA -0.00307112 0.00023035 -13.332 < 0.0000000000000002 ***
stateMD -0.00226145 0.00028240 -8.008 0.00000000000028970 ***
stateME -0.00580699 0.00028394 -20.451 < 0.0000000000000002 ***
stateMI -0.00261719 0.00027827 -9.405 < 0.0000000000000002 ***
stateMN -0.00467744 0.00027726 -16.870 < 0.0000000000000002 ***
stateMO -0.00222256 0.00027575 -8.060 0.00000000000021527 ***
stateMS -0.00427042 0.00026828 -15.918 < 0.0000000000000002 ***
stateMT -0.00364065 0.00027312 -13.330 < 0.0000000000000002 ***
stateNC -0.00351146 0.00026909 -13.049 < 0.0000000000000002 ***
stateND -0.00435704 0.00022522 -19.345 < 0.0000000000000002 ***
stateNE -0.00422841 0.00028351 -14.914 < 0.0000000000000002 ***
stateNH -0.00499346 0.00028503 -17.519 < 0.0000000000000002 ***
stateNJ -0.00443768 0.00028050 -15.820 < 0.0000000000000002 ***
stateNM -0.00056434 0.00026533 -2.127 0.03505 *
stateNV -0.00122579 0.00072234 -1.697 0.09176 .
stateNY -0.00323640 0.00022823 -14.180 < 0.0000000000000002 ***
stateOH -0.00409035 0.00027859 -14.682 < 0.0000000000000002 ***
stateOK -0.00258715 0.00026694 -9.692 < 0.0000000000000002 ***
stateOR -0.00443097 0.00028468 -15.565 < 0.0000000000000002 ***
statePA -0.00382159 0.00027513 -13.890 < 0.0000000000000002 ***
stateRI -0.00461594 0.00029420 -15.690 < 0.0000000000000002 ***
stateSC -0.00183411 0.00027537 -6.660 0.00000000047726822 ***
stateSD -0.00324702 0.00025773 -12.598 < 0.0000000000000002 ***
stateTN -0.00075813 0.00027152 -2.792 0.00591 **
stateTX -0.00277209 0.00024685 -11.230 < 0.0000000000000002 ***
stateUT -0.00472267 0.00025786 -18.315 < 0.0000000000000002 ***
stateVA -0.00503090 0.00025307 -19.879 < 0.0000000000000002 ***
stateVT -0.00590757 0.00025777 -22.918 < 0.0000000000000002 ***
stateWA -0.00408172 0.00028349 -14.398 < 0.0000000000000002 ***
stateWI -0.00407603 0.00028290 -14.408 < 0.0000000000000002 ***
stateWV -0.00373564 0.00026742 -13.969 < 0.0000000000000002 ***
stateWY -0.00490828 0.00025467 -19.273 < 0.0000000000000002 ***
year 0.00008585 0.00001514 5.669 0.00000007092442572 ***
var 0.00243152 0.00244261 0.995 0.32111
Residual standard error: 0.0002384 on 151 degrees of freedom
Multiple R-squared: 0.989, Adjusted R-squared: 0.9853
F-statistic: 262 on 52 and 151 DF, p-value: < 0.00000000000000022
state_data %>%
filter(countystat == 'poverty_rate') %>%
select(var) %>%
unique() %>%
ggplot(aes(x = var)) +
geom_density()


plot(as.party(rpart(state_vcrime_rate ~ ., data = state_data)))
plot(as.party(rpart(state_vcrime_rate ~ var + state_avg_income, data = state_data %>% filter(countystat == 'income'))))
state_data_pca <- state_data_pca_df[, -2] %>%
prcomp(scale = TRUE)
-1 * state_data_pca$rotation[, 1:4] %>% round(3)
PC1 PC2 PC3 PC4
year -0.002 -0.049 0.190 -0.593
n_counties -0.246 0.111 -0.228 0.179
state_total_count -0.419 -0.037 0.120 0.051
state_area -0.088 -0.024 -0.051 -0.037
state_pop_dens 0.068 -0.529 -0.006 0.106
state_avg_income 0.037 -0.333 0.509 0.110
state_p_farm_income 0.076 0.141 -0.177 0.673
state_empl_count -0.417 -0.047 0.138 0.062
state_empl_rate 0.131 -0.468 0.119 0.273
state_poverty_count -0.426 -0.039 0.050 0.034
state_poverty_rate -0.137 -0.057 -0.550 -0.196
violent_crime -0.419 -0.074 0.066 0.014
state_vcrime_rate -0.018 -0.474 -0.245 -0.109
property_crime -0.421 -0.049 0.022 0.047
state_pcrime_rate -0.012 -0.338 -0.449 -0.066
summary(state_data_pca)
Importance of components:
PC1 PC2 PC3 PC4 PC5 PC6 PC7 PC8 PC9 PC10 PC11 PC12 PC13 PC14 PC15
Standard deviation 2.3236 1.7514 1.4704 1.0927 1.04345 0.9558 0.6842 0.55525 0.44079 0.34091 0.24546 0.13071 0.08364 0.05586 0.02395
Proportion of Variance 0.3599 0.2045 0.1442 0.0796 0.07259 0.0609 0.0312 0.02055 0.01295 0.00775 0.00402 0.00114 0.00047 0.00021 0.00004
Cumulative Proportion 0.3599 0.5644 0.7086 0.7882 0.86077 0.9217 0.9529 0.97343 0.98638 0.99413 0.99815 0.99929 0.99975 0.99996 1.00000



aggregate(pca_data, by = list(pca_data$rowname), FUN = mean) %>%
ggplot(aes(x = -PC1, y = -PC2)) +
geom_text(aes(label = Group.1), size = 3)
argument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NA

pca_data_alt <- aggregate(pca_data, by = list(pca_data$rowname), FUN = mean)
argument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NA
rownames(pca_data_alt) <- pca_data_alt$Group.1
pca_data_alt <- pca_data_alt[, 3:17]
pca_data_alt %>%
dist() %>%
hclust() %>%
plot(cex = 0.8)

pca_data2 %>%
dist() %>%
hclust() %>%
plot(cex = 0.8, labels = pca_data2$rowname)
NAs introduced by coercion

# visualization
df <- aggregate(state_poverty_rate ~ state, data = state_data, mean)
df <- filter(df,
state != "DC")
mycolors_True <- brewer.pal(9, "GnBu")
states <- tolower(rownames(USArrests))
map_50S <- map_data("state")
ggplot(data = df,
aes(fill = state_poverty_rate)) +
labs(x = "Longitude", y = "Latitude", title = "Average Poverty Rate in States") +
geom_map(aes(map_id = states), map = map_50S) +
expand_limits(x = map_50S$long, y = map_50S$lat) +
theme_bw() +
scale_fill_gradientn(name = "Poverty Rate", colours = mycolors_True,
na.value = "grey")



aggregate(state_pcrime_rate ~ state, data = state_data, mean) %>%
ggplot(aes(x = state,
y = state_pcrime_rate,
colour = state,
group = state)) +
geom_label(aes(label = state), check_overlap = TRUE)+
labs(x = "State",
y = "Average State Property Crime Rate Per state (including DC)",
title = "Average State Property Crime Rate Per state (including DC)")
Ignoring unknown parameters: check_overlap



LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CiMgY2xlYW4gdXAgUiBlbnZpcm9ubWVudApybShsaXN0ID0gbHMoKSkKCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShtb3NhaWMpCmxpYnJhcnkocGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJ2ZXN0KQpsaWJyYXJ5KHJlc2hhcGUyKQpsaWJyYXJ5KHJlYWR4bCkKbGlicmFyeShycGFydCkKbGlicmFyeShwYXJ0eWtpdCkKbGlicmFyeShtY2x1c3QpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KG1hcHMpCmxpYnJhcnkobWFwdG9vbHMpCmxpYnJhcnkobWFwZGF0YSkKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShjbHVzdGVyKQpsaWJyYXJ5KGZwY2EpCmxpYnJhcnkoZG9QYXJhbGxlbCkKYGBgCgpgYGB7cn0KIyBvcHRpb25zCiMgZGlzcGxheSBhcyBkZWNpbWFsLCBub3Qgc2NpZW50aWZpYyBub3RhdGlvbgpvcHRpb25zKHNjaXBlbiA9IDk5OSkKCiMgZGF0YSBmb3IgMjAxMyAtIDIwMTYKY291bnR5X3BvdmVydHkgPC0gcmVhZC5jc3YoZmlsZSA9ICdjb3VudHlfcG92ZXJ0eV9oaXN0LmNzdicsIGhlYWRlciA9IFRSVUUsIHNlcCA9ICcsJykKY291bnR5X3BvdmVydHkkZ2VvX3N1bWxldmVsIDwtIGdzdWIoJ1tbOnB1bmN0Ol1dXFxzJywgJycsIHN0cl9leHRyYWN0KGNvdW50eV9wb3ZlcnR5JGdlb19uYW1lLCAnXFwsXFxzW0EtWl17Mn0nKSkKY291bnR5X3BvdmVydHkkZ2VvX25hbWUgPC0gZ3N1YignXFwsXFxzW0EtWl17Mn0nLCAnJywgY291bnR5X3BvdmVydHkkZ2VvX25hbWUpCmNvdW50eV9wb3ZlcnR5IDwtIGNvdW50eV9wb3ZlcnR5Wy0zXQoKIyBuYW1pbmcgc2NoZW1lOgojIHBZRUFSID0gbnVtYmVyIG9mIHBlb3BsZSBpbiBwb3ZlcnR5LCBmb3IgdGhlIGdpdmVuIHllYXIKIyBwcllFQVIgPSBwb3ZlcnR5IHJhdGUsIGZvciB0aGUgZ2l2ZW4geWVhcgojIHBvcFlFQVIgPSB0b3RhbCBwb3B1bGF0aW9uLCBmb3IgdGhlIGdpdmVuIHllYXIKbmFtZXMoY291bnR5X3BvdmVydHkpIDwtIGMoJ2NvdW50eScsICdzdGF0ZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAncDIwMTMnLCAncDIwMTQnLCAncDIwMTUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ByMjAxMycsICdwcjIwMTQnLCAncHIyMDE1JywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICdwcjIwMTYnLCAncDIwMTYnLCAncG9wMjAxMycsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAncG9wMjAxNCcsICdwb3AyMDE1JywgJ3BvcDIwMTYnKQoKY291bnR5X3BvdmVydHkgPC0gY291bnR5X3BvdmVydHkgJT4lIAogIG5hLm9taXQoKSAlPiUKICBzZWxlY3Qoc29ydChjdXJyZW50X3ZhcnMoKSkpCgojIHJlbW92ZSBQdWVydG8gUmljbwpjb3VudHlfcG92ZXJ0eSA8LSBjb3VudHlfcG92ZXJ0eSAlPiUgCiAgZmlsdGVyKHN0YXRlICE9ICdQUicpCgpjb3VudHlfcG92ZXJ0eSA8LSBjb3VudHlfcG92ZXJ0eSAlPiUgCiAgc2VsZWN0KHNvcnQoY3VycmVudF92YXJzKCkpKQpgYGAKCmBgYHtyfQojIGVjb25vbWljL3VuZW1wbG95bWVudCBkYXRhCiMgaHR0cHM6Ly9hcHBzLmJlYS5nb3YvcmVnaW9uYWwvCmVjIDwtIHJlYWQuY3N2KCdDQUlOQzRfX0FMTF9TVEFURVNfMTk2OV8yMDE3LmNzdicsIGhlYWRlciA9IFRSVUUsIHNlcCA9ICcsJykKZWMgPC0gZWNbLCBjKCdHZW9GSVBTJywgJ0dlb05hbWUnLCAnRGVzY3JpcHRpb24nLCAnWDIwMTMnLCAnWDIwMTQnLCAnWDIwMTUnLCAnWDIwMTYnKV0KZWMkRGVzY3JpcHRpb24gPC0gZ3N1YignW1s6cHVuY3Q6XV0nLCAnJywgZWMkRGVzY3JpcHRpb24pICU+JSAKICB0cmltd3MoKQoKIyBrZWVwICdQZXIgY2FwaXRhIHBlcnNvbmFsIGluY29tZSAoZG9sbGFycykgNC8nLCAnVG90YWwgZW1wbG95bWVudCcsICdGYXJtIHByb3ByaWV0b3JzJyBpbmNvbWUnLCAnTm9uZmFybSBwcm9wcmlldG9ycycgaW5jb21lJwojIGNsZWFuIGRhdGEKZWMgPC0gZWMgJT4lIAogIGZpbHRlcihlYyREZXNjcmlwdGlvbiA9PSAnUGVyIGNhcGl0YSBwZXJzb25hbCBpbmNvbWUgZG9sbGFycyA0JyB8IAogICAgICAgICAgICAgICAgICAgICAgZWMkRGVzY3JpcHRpb24gPT0gJ1RvdGFsIGVtcGxveW1lbnQnIHwgCiAgICAgICAgICAgICAgICAgICAgICBlYyREZXNjcmlwdGlvbiA9PSAnRmFybSBwcm9wcmlldG9ycyBpbmNvbWUnIHwgCiAgICAgICAgICAgICAgICAgICAgICBlYyREZXNjcmlwdGlvbiA9PSAnTm9uZmFybSBwcm9wcmlldG9ycyBpbmNvbWUnKQplYyREZXNjcmlwdGlvbltlYyREZXNjcmlwdGlvbiA9PSAnUGVyIGNhcGl0YSBwZXJzb25hbCBpbmNvbWUgZG9sbGFycyA0J10gPC0gJ2luY29tZScKZWMkRGVzY3JpcHRpb25bZWMkRGVzY3JpcHRpb24gPT0gJ1RvdGFsIGVtcGxveW1lbnQnXSA8LSAnZW1wbF9jb3VudCcKZWMkRGVzY3JpcHRpb25bZWMkRGVzY3JpcHRpb24gPT0gJ0Zhcm0gcHJvcHJpZXRvcnMgaW5jb21lJ10gPC0gJ2Zhcm1faW5jb21lJwplYyREZXNjcmlwdGlvbltlYyREZXNjcmlwdGlvbiA9PSAnTm9uZmFybSBwcm9wcmlldG9ycyBpbmNvbWUnXSA8LSAnbm9uZmFybV9pbmNvbWUnCgplYyA8LSBkY2FzdChtZWx0KGVjLCAKICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygnR2VvRklQUycsICdHZW9OYW1lJywgJ0Rlc2NyaXB0aW9uJyksIAogICAgICAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IGMoJ1gyMDEzJywgJ1gyMDE0JywgJ1gyMDE1JywgJ1gyMDE2JykpLCAKICAgICAgICAgICAgR2VvRklQUyArIEdlb05hbWUgKyB2YXJpYWJsZSB+IERlc2NyaXB0aW9uKSAlPiUgCiAgbXV0YXRlKHZhcmlhYmxlID0gZ3N1YignWCcsICcnLCB2YXJpYWJsZSkpCgplY1ssIDE6Ml0gPC0gbGFwcGx5KGVjWywgMToyXSwgYXMuY2hhcmFjdGVyKQplY1ssIGMoMSwgMzo3KV0gPC0gbGFwcGx5KGVjWywgYygxLCAzOjcpXSwgYXMubnVtZXJpYykKZWMkcF9mYXJtX2luY29tZSA8LSBlYyRmYXJtX2luY29tZSAvIGVjJG5vbmZhcm1faW5jb21lCmVjW2lzLm5hKGVjKV0gPC0gMAoKIyBjb21iaW5lIGVjb25vbWljIGRhdGEgd2l0aCBsYW5kIGFyZWEKYXJlYSA8LSByZWFkX2V4Y2VsKCdMTkQwMS54bHMnKVssYygyLDQpXQpuYW1lcyhhcmVhKSA8LSBjKCdHZW9GSVBTJywgJ2FyZWEnKQphcmVhIDwtIGxhcHBseShhcmVhLCBhcy5udW1lcmljKQplYyA8LSBtZXJnZShlYywgYXJlYSwgYnkgPSAnR2VvRklQUycpCgojIHN0YXRlIGRhdGEKIyMgQ09NQklORSBXSVRIICdTVEFURV9EQVRBJyBEQVRBIEZSQU1FCnN0YXRlX2VjIDwtIGVjWyhlYyRHZW9GSVBTICUlIDEwMDAgPT0gMCksIF0Kc3RhdGVfZWMgPC0gc3RhdGVfZWMgJT4lIAogIGZpbHRlcihHZW9GSVBTIDwgOTAwMDAgJiBHZW9GSVBTICE9IDApCnN0YXRlX2VjIDwtIHN1YnNldChzdGF0ZV9lYywgc2VsZWN0ID0gLWMoR2VvRklQUykpCm5hbWVzKHN0YXRlX2VjKSA8LSBjKCdzdGF0ZScsICd5ZWFyJywgJ2VtcGxfY291bnQnLCAnZmFybV9pbmNvbWUnLCAnaW5jb21lJywgJ25vbmZhcm1faW5jb21lJywgJ3BfZmFybV9pbmNvbWUnLCAnYXJlYScpCmBgYAoKYGBge3J9CiMgY3JlYXRlIHRhbGwgZGF0YSBzZXQKY3AxIDwtIGdhdGhlcihjb3VudHlfcG92ZXJ0eVtjKDE6NSwgMTQpXSwgeWVhciwgcG92ZXJ0eV9jb3VudCwgcDIwMTM6cDIwMTYsIGZhY3Rvcl9rZXkgPSBUUlVFKSAlPiUgCiAgbXV0YXRlKHllYXIgPSBzdHJfZXh0cmFjdCh5ZWFyLCAnXFxkezR9JykpCmNwMiA8LSBnYXRoZXIoY291bnR5X3BvdmVydHlbYygxLCA2OjksIDE0KV0sIHllYXIsIHRvdGFsX2NvdW50LCBwb3AyMDEzOnBvcDIwMTYsIGZhY3Rvcl9rZXkgPSBUUlVFKSAlPiUgCiAgbXV0YXRlKHllYXIgPSBzdHJfZXh0cmFjdCh5ZWFyLCAnXFxkezR9JykpCmNwIDwtIG1lcmdlKGNwMSwgY3AyLCBieSA9IGMoJ2NvdW50eScsICdzdGF0ZScsICd5ZWFyJykpICU+JSAKICBtdXRhdGUocG92ZXJ0eV9yYXRlID0gcG92ZXJ0eV9jb3VudCAvIHRvdGFsX2NvdW50LAogICAgICAgICB5ZWFyID0geWVhciAlPiUgYXMubnVtZXJpYygpKQoKY3AkY291bnR5IDwtIGdzdWIoJ1xcc0NvdW50eScsICcnLCBjcCRjb3VudHkpCmNwJGNvdW50eSA8LSBnc3ViKCdcXHNQYXJpc2gnLCAnJywgY3AkY291bnR5KQpjcCRjb3VudHkgPC0gZ3N1YignXFxzY2l0eScsICdcXHNDaXR5JywgY3AkY291bnR5KQpjcCRjb3VudHkgPC0gZ3N1YignW1s6cHVuY3Q6XV0nLCAnJywgY3AkY291bnR5KQpjcCRjb3VudHkgPC0gY3AkY291bnR5ICU+JSAKICB0cmltd3MoKQoKIyBjb3VudHkgZGF0YQpjb3VudHlfZWMgPC0gZWNbIShlYyRHZW9GSVBTICUlIDEwMDAgPT0gMCksIF0KY291bnR5X2VjIDwtIHN1YnNldChjb3VudHlfZWMsIHNlbGVjdCA9IC1jKEdlb0ZJUFMpKQpjb3VudHlfZWMkc3RhdGUgPC0gZ3N1YignW1s6cHVuY3Q6XV1cXHMnLCAnJywgc3RyX2V4dHJhY3QoY291bnR5X2VjJEdlb05hbWUsICdcXCxcXHNbQS1aXXsyfScpKQpjb3VudHlfZWMkR2VvTmFtZSA8LSBnc3ViKCdcXCxcXHNbQS1aXXsyfScsICcnLCBjb3VudHlfZWMkR2VvTmFtZSkKbmFtZXMoY291bnR5X2VjKSA8LSBjKCdjb3VudHknLCAneWVhcicsICdlbXBsX2NvdW50JywgJ2Zhcm1faW5jb21lJywgJ2luY29tZScsICdub25mYXJtX2luY29tZScsICdwX2Zhcm1faW5jb21lJywgJ2FyZWEnLCAnc3RhdGUnKQoKY291bnR5X2VjJGNvdW50eSA8LSBnc3ViKCdbWzpwdW5jdDpdXScsICcnLCBjb3VudHlfZWMkY291bnR5KQpjb3VudHlfZWMkY291bnR5IDwtIGdzdWIoJ1xcc0luZGVwZW5kZW50XFxzQ2l0eScsICdcXHNDaXR5JywgY291bnR5X2VjJGNvdW50eSkKY291bnR5X2VjJGNvdW50eSA8LSBnc3ViKCdcXHNTdGF1bnRvblxcc1dheW5lc2Jvcm8nLCAnJywgY291bnR5X2VjJGNvdW50eSkKYGBgCgpgYGB7cn0KIyBtYW51YWwgZml4IGZvciBjb3VudGllcyB3aXRoIGFyZWEgPSAwCiMgc2NyYXBlIGFyZWFzIGZyb20gV2lraXBlZGlhLCBhcyBDZW5zdXMgZGF0YSB3YXMgaW5hZGVxdWF0ZQp6ZXJvYXJlYSA8LSBjb3VudHlfZWNbd2hpY2goY291bnR5X2VjJGFyZWEgPT0gMCksIC1jKDI6NyldICU+JSAKICB1bmlxdWUoKQp6ZXJvYXJlYSR3aWtpX2xpbmsgPC0gZ3N1YignIENpdHkgYW5kIEJvcm91Z2gnLCAnJywgemVyb2FyZWEkY291bnR5KQp6ZXJvYXJlYSR3aWtpX2xpbmsgPC0gZ3N1YignIE11bmljaXBhbGl0eScsICcnLCB6ZXJvYXJlYSR3aWtpX2xpbmspCnplcm9hcmVhJHdpa2lfbGluayA8LSBnc3ViKCdbQS1aXXsyfScsICcnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ2h0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpLycsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc3ViKCdcXHMnLCAnXycsIHplcm9hcmVhJHdpa2lfbGluayksICcsXycsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc3ViKCdBSycsICdBbGFza2EnLCB6ZXJvYXJlYSRzdGF0ZSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc3ViKCdDTycsICdDb2xvcmFkbycsIHplcm9hcmVhJHN0YXRlKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICcnKSkKCmZvcihpIGluIDE6bnJvdyh6ZXJvYXJlYSkpIHsKICB6ZXJvYXJlYSRhcmVhW2ldIDwtIGdzdWIoJywnLCAnJywgcmVhZF9odG1sKHplcm9hcmVhJHdpa2lfbGlua1tpXSkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICBodG1sX25vZGVzKHhwYXRoID0gJy8vdGhbY29udGFpbnMoLiwgIkFyZWEiKV0vL3BhcmVudDo6dHIvZm9sbG93aW5nLXNpYmxpbmc6OnRyWzFdL3RkJykgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICBodG1sX3RleHQoKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cl9leHRyYWN0KCdbXFxkXFwuLF0rJykpWzFdICU+JSAKICBhcy5udW1lcmljKCkKICBjb3VudHlfZWMkYXJlYVt3aGljaChjb3VudHlfZWMkY291bnR5ID09IHplcm9hcmVhJGNvdW50eVtpXSldIDwtIHplcm9hcmVhJGFyZWFbd2hpY2goemVyb2FyZWEkY291bnR5ID09IHplcm9hcmVhJGNvdW50eVtpXSldCn0KYGBgCgpgYGB7cn0KY291bnR5X2RhdGEgPC0gbWVyZ2UoY3AsIGNvdW50eV9lYywgYnkgPSBjKCdjb3VudHknLCAnc3RhdGUnLCAneWVhcicpKSAlPiUgCiAgbXV0YXRlKGVtcGxfcmF0ZSA9IGVtcGxfY291bnQgLyB0b3RhbF9jb3VudCwgCiAgICAgICAgIHBvcF9kZW5zID0gdG90YWxfY291bnQgLyBhcmVhKQoKIyAnY291bnR5X2RhdGEnIHRvIHdpZGUKc3QgPC0gbGlzdCgpCmZvciAoaSBpbiAyMDEzOjIwMTYpIHsKICBkZiA8LSBjb3VudHlfZGF0YSAlPiUgCiAgICBmaWx0ZXIoeWVhciA9PSBpKQogIGRmIDwtIGRmWywgLTNdCiAgZGZfbmFtZXMgPC0gbmFtZXMoZGYpCiAgZGZfbmFtZXNbM10gPC0gcGFzdGUoJ3AnLCBpICU+JSBhcy5jaGFyYWN0ZXIoKSwgc2VwID0gJycpCiAgZGZfbmFtZXNbNF0gPC0gcGFzdGUoJ3BvcCcsIGkgJT4lIGFzLmNoYXJhY3RlcigpLCBzZXAgPSAnJykKICBkZl9uYW1lc1s1XSA8LSBwYXN0ZSgncHInLCBpICU+JSBhcy5jaGFyYWN0ZXIoKSwgc2VwID0gJycpCiAgZGZfbmFtZXNbNl0gPC0gcGFzdGUoJ2VjJywgaSAlPiUgYXMuY2hhcmFjdGVyKCksIHNlcCA9ICcnKQogIGRmX25hbWVzWzddIDwtIHBhc3RlKCdmX2luYycsIGkgJT4lIGFzLmNoYXJhY3RlcigpLCBzZXAgPSAnJykKICBkZl9uYW1lc1s4XSA8LSBwYXN0ZSgnaW5jJywgaSAlPiUgYXMuY2hhcmFjdGVyKCksIHNlcCA9ICcnKQogIGRmX25hbWVzWzldIDwtIHBhc3RlKCduZl9pbmMnLCBpICU+JSBhcy5jaGFyYWN0ZXIoKSwgc2VwID0gJycpCiAgZGZfbmFtZXNbMTBdIDwtIHBhc3RlKCdwZl9pbmMnLCBpICU+JSBhcy5jaGFyYWN0ZXIoKSwgc2VwID0gJycpCiAgZGZfbmFtZXNbMTJdIDwtIHBhc3RlKCdlcicsIGkgJT4lIGFzLmNoYXJhY3RlcigpLCBzZXAgPSAnJykKICBkZl9uYW1lc1sxM10gPC0gcGFzdGUoJ3BvcF9kZW5zJywgaSAlPiUgYXMuY2hhcmFjdGVyKCksIHNlcCA9ICcnKQogIG5hbWVzKGRmKSA8LSBkZl9uYW1lcwogIHN0W1tpIC0gMjAxMl1dIDwtIGRmCn0KCmNvdW50eV9kYXRhX3dpZGUgPC0gbWVyZ2Uoc3RbWzFdXSwgc3RbWzJdXSwgYnkgPSBjKCdzdGF0ZScsICdjb3VudHknLCAnYXJlYScpKQpjb3VudHlfZGF0YV93aWRlIDwtIG1lcmdlKGNvdW50eV9kYXRhX3dpZGUsIHN0W1szXV0sIGJ5ID0gYygnc3RhdGUnLCAnY291bnR5JywgJ2FyZWEnKSkKY291bnR5X2RhdGFfd2lkZSA8LSBtZXJnZShjb3VudHlfZGF0YV93aWRlLCBzdFtbNF1dLCBieSA9IGMoJ3N0YXRlJywgJ2NvdW50eScsICdhcmVhJykpCmBgYAoKYGBge3J9CiMgZGF0YSBzZXQgb2YgcG92ZXJ0eSwgYnkgc3RhdGUKc3RhdGVfcG92ZXJ0eSA8LSB0YWJsZShjb3VudHlfZGF0YV93aWRlJHN0YXRlKSAlPiUgCiAgZGF0YS5mcmFtZSgpCm5hbWVzKHN0YXRlX3BvdmVydHkpIDwtIGMoJ3N0YXRlJywgJ25fY291bnRpZXMnKQoKIyA1MSA9IG51bWJlciBvZiBzdGF0ZXMsIGluY2x1ZGluZyBXYXNoaW5ndG9uIEQuQy4KCiMgY3JlYXRlIGEgZGF0YSB0YWJsZSBvZiBzdW1tYXJ5IHN0YXRzIHBlciBzdGF0ZQpzcCA8LSBsaXN0KCkKZm9yKGkgaW4gMTo1MSkgewogIHN0YXRlX3N0YXRzIDwtIGRhdGEuZnJhbWUoc3VtbWFyeShjb3VudHlfZGF0YV93aWRlW3doaWNoKGNvdW50eV9kYXRhX3dpZGUkc3RhdGUgPT0gc3RhdGVfcG92ZXJ0eSRzdGF0ZVtpXSksIF0pKVsxMzoyNTgsIDI6M10gJT4lIAogIG11dGF0ZShzdGF0ID0gZ3N1YignXFxzKlxcOicsICcnLCBzdHJfZXh0cmFjdChGcmVxLCAnLipcXDonKSksIAogICAgICAgICBGcmVxID0gZ3N1YignOicsICcnLCBzdHJfZXh0cmFjdChGcmVxLCAnXFw6LisnKSkgJT4lIGFzLm51bWVyaWMoKSkgJT4lIAogIHJlc2hhcGUoaWR2YXIgPSAnVmFyMicsIHRpbWV2YXIgPSAnc3RhdCcsIGRpcmVjdGlvbiA9ICd3aWRlJykgJT4lCiAgbXV0YXRlKFllYXIgPSBzdHJfZXh0cmFjdChWYXIyLCAnXFxkezR9JyksIAogICAgICAgICBWYXIyID0gc3RyX2V4dHJhY3QoVmFyMiwgJ1thLXpfXXsxLDd9JyksIAogICAgICAgICBzdGF0ZSA9IHN0YXRlX3BvdmVydHkkc3RhdGVbaV0pCiAgc3BbW2ldXSA8LSBzdGF0ZV9zdGF0cwp9CgojIGNsZWFuIGRhdGEsIHJlbmFtZSB2YXJpYWJsZXMgYW5kIHJlb3JnYW5pemUgY29sdW1uIG9yZGVyCnN0YXRlX3BvdmVydHkgPC0gbWVyZ2Uoc3RhdGVfcG92ZXJ0eSwgZG8uY2FsbChyYmluZCwgc3ApLCBieSA9ICdzdGF0ZScpICU+JSAKICBzZWxlY3Qoc29ydChjdXJyZW50X3ZhcnMoKSkpCnN0YXRlX3BvdmVydHkgPC0gc3RhdGVfcG92ZXJ0eVssIGMoOCwgMTAsIDcsIDksIDE6NildCnN0YXRlX3BvdmVydHkkVmFyMltzdGF0ZV9wb3ZlcnR5JFZhcjIgPT0gJ3AnXSA8LSAncG92ZXJ0eV9jb3VudCcKc3RhdGVfcG92ZXJ0eSRWYXIyW3N0YXRlX3BvdmVydHkkVmFyMiA9PSAncHInXSA8LSAncG92ZXJ0eV9yYXRlJwpzdGF0ZV9wb3ZlcnR5JFZhcjJbc3RhdGVfcG92ZXJ0eSRWYXIyID09ICdwb3AnXSA8LSAndG90YWxfY291bnQnCnN0YXRlX3BvdmVydHkkVmFyMltzdGF0ZV9wb3ZlcnR5JFZhcjIgPT0gJ2VjJ10gPC0gJ2VtcGxfY291bnQnCnN0YXRlX3BvdmVydHkkVmFyMltzdGF0ZV9wb3ZlcnR5JFZhcjIgPT0gJ2ZfaW5jJ10gPC0gJ2Zhcm1faW5jb21lJwpzdGF0ZV9wb3ZlcnR5JFZhcjJbc3RhdGVfcG92ZXJ0eSRWYXIyID09ICdpbmMnXSA8LSAnaW5jb21lJwpzdGF0ZV9wb3ZlcnR5JFZhcjJbc3RhdGVfcG92ZXJ0eSRWYXIyID09ICdmX2luYyddIDwtICdmYXJtX2luY29tZScKc3RhdGVfcG92ZXJ0eSRWYXIyW3N0YXRlX3BvdmVydHkkVmFyMiA9PSAnbmZfaW5jJ10gPC0gJ25vbmZhcm1faW5jb21lJwpzdGF0ZV9wb3ZlcnR5JFZhcjJbc3RhdGVfcG92ZXJ0eSRWYXIyID09ICdwZl9pbmMnXSA8LSAncF9mYXJtX2luY29tZScKc3RhdGVfcG92ZXJ0eSRWYXIyW3N0YXRlX3BvdmVydHkkVmFyMiA9PSAnZXInXSA8LSAnZW1wbF9yYXRlJwpzdGF0ZV9wb3ZlcnR5JFZhcjJbc3RhdGVfcG92ZXJ0eSRWYXIyID09ICdhcmVhJ10gPC0gJ2FyZWEnCnN0YXRlX3BvdmVydHkkVmFyMltzdGF0ZV9wb3ZlcnR5JFZhcjIgPT0gJ3BvcF9kZW4nXSA8LSAncG9wX2RlbnMnCm5hbWVzKHN0YXRlX3BvdmVydHkpIDwtIGMoJ3N0YXRlJywgJ3llYXInLCAnbl9jb3VudGllcycsICdjb3VudHlzdGF0JywgJzFzdF9xdWFudGlsZScsICczcmRfcXVhbnRpbGUnLCAnbWF4JywgJ21lYW4nLCAnbWVkaWFuJywgJ21pbmltdW0nKQoKIyByZXBsYWNlIE5BcyBmb3IgJ3llYXInCmZvcihpIGluIDE6bnJvdyhzdGF0ZV9wb3ZlcnR5KSkgewogIGlmKHN0YXRlX3BvdmVydHkkeWVhcltpXSAlPiUgaXMubmEpIHsKICAgIHN0YXRlX3BvdmVydHkkeWVhcltpXSA8LSBzdGF0ZV9wb3ZlcnR5JHllYXJbaSArIDFdCiAgfQp9CgojIGNyZWF0ZSB2YXJpYWJsZXMgbWVhc3VyaW5nIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gYW5kIHZhcmlhbmNlIG9mIGNvdW50eSBzdGF0cywgcGVyIHllYXIKc3RhdGVfdmFyaWFuY2UgPC0gYygpCnN0YXRlX3NkIDwtIGMoKQpmb3IoaSBpbiAxOm5yb3coc3RhdGVfcG92ZXJ0eSkpIHsKICBzdGF0ZV92YXJpYW5jZVtpXSA8LSBjb3VudHlfZGF0YSAlPiUgCiAgICBmaWx0ZXIoc3RhdGUgPT0gc3RhdGVfcG92ZXJ0eSRzdGF0ZVtpXSAmIHllYXIgPT0gc3RhdGVfcG92ZXJ0eSR5ZWFyW2ldKSAlPiUgCiAgICBzZWxlY3Qoc3RhdGVfcG92ZXJ0eSRjb3VudHlzdGF0W2ldKSAlPiUgCiAgICB2YXIoKQogIHN0YXRlX3NkW2ldIDwtIHNhcHBseShjb3VudHlfZGF0YSAlPiUgZmlsdGVyKHN0YXRlID09IHN0YXRlX3BvdmVydHkkc3RhdGVbaV0gJiB5ZWFyID09IHN0YXRlX3BvdmVydHkkeWVhcltpXSkgJT4lIHNlbGVjdChzdGF0ZV9wb3ZlcnR5JGNvdW50eXN0YXRbaV0pLCBzZClbWzFdXVsxXQp9CgpzdGF0ZV9wb3ZlcnR5JHZhciA8LSBzdGF0ZV92YXJpYW5jZQpzdGF0ZV9wb3ZlcnR5JHNkIDwtIHN0YXRlX3NkCnN0YXRlX3BvdmVydHlbaXMubmEoc3RhdGVfcG92ZXJ0eSldIDwtIDAKCiMgbWVyZ2Ugc3RhdGUgc3RhdHMgd2l0aCBzdGF0aXN0aWNzIG9uIHRvdGFsIHN0YXRlIHBvcHVsYXRpb24gKCdzdGF0ZV9lYycpLCB0b3RhbCBzdGF0ZSBwb3ZlcnR5IGNvdW50LCBhbmQgb3ZlcmFsbCBzdGF0ZSBwb3ZlcnR5IHJhdGUgKGFnZ3JlZ2F0aW5nICdjcCcpCiMgY2hhbmdlICdzdGF0ZV9lYycgbmFtZXMgZnJvbSBmdWxsIHdvcmRzIHRvIDItbGV0dGVyIGFiYnJldmlhdGlvbnMKZm9yKGkgaW4gMTpucm93KHN0YXRlX2VjKSkgewogIGlmKHN0YXRlX2VjJHN0YXRlW2ldID09ICdEaXN0cmljdCBvZiBDb2x1bWJpYScpIHsKICAgIHN0YXRlX2VjJHN0YXRlW2ldIDwtICdEQycKICB9IGVsc2UgewogICAgc3RhdGVfZWMkc3RhdGVbaV0gPC0gc3RhdGUuYWJiW2dyZXAoc3RhdGVfZWMkc3RhdGVbaV0sIHN0YXRlLm5hbWUpXQogIH0KfQoKc3RhdGVfZWMgPC0gbWVyZ2Uoc3RhdGVfZWMsIAogICAgICAgICAgICAgICAgICBtZXJnZShhZ2dyZWdhdGUocG92ZXJ0eV9jb3VudCB+IHN0YXRlICsgeWVhciwgY3AsIHN1bSksIAogICAgICAgICAgICAgICAgICAgICAgICBhZ2dyZWdhdGUodG90YWxfY291bnQgfiBzdGF0ZSArIHllYXIsIGNwLCBzdW0pLCAKICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCdzdGF0ZScsICd5ZWFyJykpLCAKICAgICAgICAgICAgICAgICAgYnkgPSBjKCdzdGF0ZScsICd5ZWFyJykpICU+JSAKICBtdXRhdGUocG92ZXJ0eV9yYXRlID0gcG92ZXJ0eV9jb3VudCAvIHRvdGFsX2NvdW50LCAKICAgICAgICAgZW1wbF9yYXRlID0gZW1wbF9jb3VudCAvIHRvdGFsX2NvdW50KQoKc3RhdGVfZWMgPC0gbWVyZ2Uoc3RhdGVfcG92ZXJ0eSwgc3RhdGVfZWMsIGJ5ID0gYygnc3RhdGUnLCAneWVhcicpKQoKIyByZW5hbWUgc3RhdGUtd2lkZSB2YXJpYWJsZXMgZm9yIGNsYXJpdHkKbmFtZXMoc3RhdGVfZWMpIDwtIGMoJ3N0YXRlJywgJ3llYXInLCAnbl9jb3VudGllcycsICdjb3VudHlzdGF0JywgJzFzdF9xdWFudGlsZScsICczcmRfcXVhbnRpbGUnLCAnbWF4JywgJ21lYW4nLCAnbWVkaWFuJywgJ21pbmltdW0nLCAndmFyJywgJ3NkJywgJ3N0YXRlX2VtcGxfY291bnQnLCAnc3RhdGVfZmFybV9pbmNvbWUnLCAnc3RhdGVfYXZnX2luY29tZScsICdzdGF0ZV9ub25mYXJtX2luY29tZScsICdzdGF0ZV9wX2Zhcm1faW5jb21lJywgJ3N0YXRlX2FyZWEnLCAnc3RhdGVfcG92ZXJ0eV9jb3VudCcsICdzdGF0ZV90b3RhbF9jb3VudCcsICdzdGF0ZV9wb3ZlcnR5X3JhdGUnLCAnc3RhdGVfZW1wbF9yYXRlJykKYGBgCgoKYGBge3J9CiMgcGVyLXN0YXRlIGNyaW1lIGRhdGEsIG1lcmdlIHdpdGggJ3N0YXRlX2RhdGEnCnN0YXRlX2NyaW1lIDwtIHJlYWQuY3N2KGZpbGUgPSAnZXN0aW1hdGVkX2NyaW1lcy5jc3YnLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAnLCcpCnN0YXRlX2RhdGEgPC0gbWVyZ2Uoc3RhdGVfZWMsIHN0YXRlX2NyaW1lWywgLWMoMiwgNDo1LCAxNSldLCAKICAgICAgICAgICAgICAgICAgICBieS54ID0gYygneWVhcicsICdzdGF0ZScpLCBieS55ID0gYygneWVhcicsICdzdGF0ZV9hYmJyJykpICU+JSAKICBtdXRhdGUoc3RhdGVfdmNyaW1lX3JhdGUgPSB2aW9sZW50X2NyaW1lIC8gc3RhdGVfdG90YWxfY291bnQsCiAgICAgICAgIHN0YXRlX3BjcmltZV9yYXRlID0gcHJvcGVydHlfY3JpbWUgLyBzdGF0ZV90b3RhbF9jb3VudCwKICAgICAgICAgc3RhdGVfcG9wX2RlbnMgPSBzdGF0ZV90b3RhbF9jb3VudCAvIHN0YXRlX2FyZWEpCnN0YXRlX2RhdGEgPC0gc3RhdGVfZGF0YVssIGMoMTozLCAyMCwgMTgsIDM0LCAxNSwgNDoxMiwgMTcsIDEzLCAyMiwgMTksIDIxLCAyMywgMzIsIDI4LCAzMyldCnN0YXRlX2RhdGEkeWVhciA8LSBzdGF0ZV9kYXRhJHllYXIgJT4lIGFzLm51bWVyaWMoKQoKIyBleHBsYWluICdzdGF0ZV9kYXRhJyB2YXJpYWJsZXMgYmVsb3cKIyB5ZWFyOiAyMDEzLTIwMTYKIyBzdGF0ZTogc3RhdGUsIHdpdGhpbiB0aGUgVW5pdGVkIFN0YXRlcwojIG5fY291bnRpZXM6IG51bWJlciBvZiBjb3VudGllcyBpbiB0aGlzIHN0YXRlCiMgc3RhdGVfdG90YWxfY291bnQ6IHN0YXRlIHBvcHVsYXRpb24KIyBjb3VudHlzdGF0OiB0eXBlIG9mIHN0YXRpc3RpYywgbWVhc3VyZWQgd2l0aGluIGNvdW50aWVzIG9mIGVhY2ggc3RhdGUKIyMgZW1wbF9jb3VudDogbnVtYmVyIG9mIGVtcGxveWVkIGluZGl2aWR1YWxzIHdvcmtpbmcgcGVyIGNvdW50eQojIyBmYXJtX2luY29tZTogYW1vdW50IG9mIGluY29tZSBmcm9tIGZhcm1pbmcgcGVyIGNvdW50eQojIyBub25mYXJtX2luY29tZTogYW1vdW50IG9mIGluY29tZSBmcm9tIG5vbi1mYXJtaW5nIGluZHVzdHJpZXMgcGVyIGNvdW50eQojIyBwX2Zhcm1faW5jb21lOiByYXRpbyBvZiAnZmFybV9pbmNvbWUnIHRvICdub25mYXJtX2luY29tZScgcGVyIGNvdW50eSwgY2FuIGJlIG5lZ2F0aXZlLCBpbmRpY2F0b3Igb2YgaG93IHJ1cmFsIGNvdW50aWVzIGFyZQojIyBlbXBsX3JhdGU6IHJhdGlvIG9mIGVtcGxveWVkIGluZGl2aWR1YWxzIHdvcmtpbmcgcGVyIGNvdW50eSwgY2FuIGJlID4xCiMjIHBvdmVydHlfcmF0ZTogcGVyY2VudGFnZSBvZiBpbmRpdmlkdWFscyBpbiBwb3ZlcnR5IHBlciBjb3VudHkKIyMgcG92ZXJ0eV9jb3VudDogbnVtYmVyIG9mIGluZGl2aWR1YWxzIGluIHBvdmVydHkgcGVyIGNvdW50eQojIyB0b3RhbF9jb3VudDogcG9wdWxhdGlvbiBwZXIgY291bnR5CiMgMXN0X3F1YW50aWxlOnNkOiBzdGF0aXN0aWNzIG9uIGNvdW50aWVzLCBwZXIgc3RhdGUgYW5kIHllYXIKIyBzdGF0ZV9hdmdfaW5jb21lOiBhdmVyYWdlIGluY29tZSBwZXIgaW5kaXZpZHVhbCBwZXIgc3RhdGUgYW5kIHllYXIKIyBzdGF0ZV9wX2Zhcm1faW5jb21lOiByYXRpbyBvZiAnZmFybV9pbmNvbWUnIHRvICdub25mYXJtX2luY29tZScgcGVyIHN0YXRlIGFuZCB5ZWFyLCBjYW4gYmUgbmVnYXRpdmUsIGluZGljYXRvciBvZiBob3cgcnVyYWwgY291bnRpZXMgYXJlCiMgc3RhdGVfcG92ZXJ0eV9jb3VudDogbnVtYmVyIG9mIGluZGl2aWR1YWxzIGluIHBvdmVydHkgcGVyIHN0YXRlIGFuZCB5ZWFyCiMgc3RhdGVfcG92ZXJ0eV9yYXRlOiBwZXJjZW50YWdlIG9mIGluZGl2aWR1YWxzIGluIHBvdmVydHkgcGVyIHN0YXRlIGFuZCB5ZWFyCiMgc3RhdGVfZW1wbF9jb3VudDogbnVtYmVyIG9mIGVtcGxveWVkIGluZGl2aWR1YWxzIHdvcmtpbmcgcGVyIHN0YXRlIGFuZCB5ZWFyCiMgc3RhdGVfZW1wbF9yYXRlOiByYXRpbyBvZiBlbXBsb3llZCBpbmRpdmlkdWFscyB3b3JraW5nIHBlciBzdGF0ZSBhbmQgeWVhcgojIHZpb2xlbnRfY3JpbWU6IG51bWJlciBvZiB2aW9sZW50IGNyaW1lcyBwZXIgc3RhdGUgYW5kIHllYXIKIyBzdGF0ZV92Y3JpbWVfcmF0ZTogcmF0ZSBvZiB2aW9sZW50IGNyaW1lcyBwZXIgc3RhdGUgYW5kIHllYXIKIyBwcm9wZXJ0eV9jcmltZTogbnVtYmVyIG9mIHByb3BlcnR5IGNyaW1lcyBwZXIgc3RhdGUgYW5kIHllYXIKIyBzdGF0ZV9wY3JpbWVfcmF0ZTogcmF0ZSBvZiBwcm9wZXJ0eSBjcmltZXMgcGVyIHN0YXRlIGFuZCB5ZWFyCgojIHNhdmUgJ3N0YXRlX2RhdGEnIGFzIC5jc3YgZmlsZQp3cml0ZS5jc3Yoc3RhdGVfZGF0YSwgZmlsZSA9ICdzdGF0ZV9kYXRhLmNzdicpCmBgYAoKYGBge3J9CiMgbm90IHRoZSB3b3JzdCByZWdyZXNzaW9ucyBldmVyIHRiaApsbShzdGF0ZV92Y3JpbWVfcmF0ZSB+IHN0YXRlICsgeWVhciArIHZhciwgCiAgIGRhdGEgPSBzdGF0ZV9kYXRhICU+JSBmaWx0ZXIoY291bnR5c3RhdCA9PSAncG92ZXJ0eV9yYXRlJykpICU+JSAKICBtc3VtbWFyeSgpCmxtKHN0YXRlX3ZjcmltZV9yYXRlIH4gc3RhdGUgKyB5ZWFyICsgdmFyLCAKICAgZGF0YSA9IHN0YXRlX2RhdGEgJT4lIGZpbHRlcihjb3VudHlzdGF0ID09ICdwb3BfZGVucycpKSAlPiUgCiAgbXN1bW1hcnkoKQpsbShzdGF0ZV92Y3JpbWVfcmF0ZSB+IHN0YXRlICsgeWVhciArIG1lYW4sIAogICBkYXRhID0gc3RhdGVfZGF0YSAlPiUgZmlsdGVyKGNvdW50eXN0YXQgPT0gJ3BfZmFybV9pbmNvbWUnKSkgJT4lIAogIG1zdW1tYXJ5KCkKbG0oc3RhdGVfdmNyaW1lX3JhdGUgfiBzdGF0ZSArIHllYXIgKyB2YXIsIAogICBkYXRhID0gc3RhdGVfZGF0YSAlPiUgZmlsdGVyKGNvdW50eXN0YXQgPT0gJ2VtcGxfcmF0ZScpKSAlPiUgCiAgbXN1bW1hcnkoKQpsbShzdGF0ZV92Y3JpbWVfcmF0ZSB+IHN0YXRlICsgeWVhciArIG1lYW4sIAogICBkYXRhID0gc3RhdGVfZGF0YSAlPiUgZmlsdGVyKGNvdW50eXN0YXQgPT0gJ2luY29tZScpKSAlPiUgCiAgICBtc3VtbWFyeSgpCgpzdGF0ZV9kYXRhICU+JSAKICBmaWx0ZXIoY291bnR5c3RhdCA9PSAncG92ZXJ0eV9yYXRlJykgJT4lIAogIHNlbGVjdCh2YXIpICU+JSAKICB1bmlxdWUoKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gdmFyKSkgKyAKICBnZW9tX2RlbnNpdHkoKQpgYGAKCmBgYHtyfQojIGRlY2lzaW9uIHRyZWVzCnJwYXJ0KHN0YXRlX3ZjcmltZV9yYXRlIH4gc3RhdGUgKyB5ZWFyLCBkYXRhID0gc3RhdGVfZGF0YSkKcnBhcnQoc3RhdGVfdmNyaW1lX3JhdGUgfiB2YXIsIGRhdGEgPSBzdGF0ZV9kYXRhICU+JSBmaWx0ZXIoY291bnR5c3RhdCA9PSAncG92ZXJ0eV9yYXRlJykpCnJwYXJ0KHN0YXRlX3ZjcmltZV9yYXRlIH4gLiwgZGF0YSA9IHN0YXRlX2RhdGEpCnJwYXJ0KHN0YXRlX3ZjcmltZV9yYXRlIH4gc3RhdGUgKyB2YXIsIGRhdGEgPSBzdGF0ZV9kYXRhICU+JSBmaWx0ZXIoY291bnR5c3RhdCA9PSAncG9wX2RlbnMnKSkKYGBgCgpgYGB7cn0KcGxvdChhcy5wYXJ0eShycGFydChzdGF0ZV92Y3JpbWVfcmF0ZSB+IC4sIGRhdGEgPSBzdGF0ZV9kYXRhKSkpCmBgYAoKYGBge3J9CnBsb3QoYXMucGFydHkocnBhcnQoc3RhdGVfdmNyaW1lX3JhdGUgfiB2YXIgKyBzdGF0ZV9hdmdfaW5jb21lLCBkYXRhID0gc3RhdGVfZGF0YSAlPiUgZmlsdGVyKGNvdW50eXN0YXQgPT0gJ2luY29tZScpKSkpCmBgYAoKYGBge3J9CnN0YXRlX2RhdGFfcGNhX2RmIDwtIHN0YXRlX2RhdGFbLGMoMTo3LCAxNzoyNSldICU+JSAKICB1bmlxdWUoKQpyb3duYW1lcyhzdGF0ZV9kYXRhX3BjYV9kZikgPC0gcGFzdGUoc3RhdGVfZGF0YV9wY2FfZGYkc3RhdGUsIHN0YXRlX2RhdGFfcGNhX2RmJHllYXIsIHNlcCA9ICcnKQoKc3RhdGVfZGF0YV9wY2EgPC0gc3RhdGVfZGF0YV9wY2FfZGZbLCAtMl0gJT4lIAogIHByY29tcChzY2FsZSA9IFRSVUUpCi0xICogc3RhdGVfZGF0YV9wY2Ekcm90YXRpb25bLCAxOjRdICU+JSByb3VuZCgzKQoKc3VtbWFyeShzdGF0ZV9kYXRhX3BjYSkKYGBgCgpgYGB7cn0KZGF0YS5mcmFtZShzZCA9IHN0YXRlX2RhdGFfcGNhJHNkZXYpICU+JSAKICByb3duYW1lc190b19jb2x1bW4oKSAlPiUgCiAgbXV0YXRlKHJvd25hbWUgPSBwYXJzZV9udW1iZXIocm93bmFtZSksIAogICAgICAgICB0b3RhbFZhciA9IHN1bShzdGF0ZV9kYXRhX3BjYSRzZGV2XjIpLCAKICAgICAgICAgcHZlID0gMTAwICogc2ReMiAvIHRvdGFsVmFyLCAKICAgICAgICAgY3VzdW0gPSBjdW1zdW0ocHZlKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHJvd25hbWUsIHkgPSBwdmUpKSArIAogIGdlb21fbGluZSgpCmBgYAoKYGBge3J9CmRhdGEuZnJhbWUoc2QgPSBzdGF0ZV9kYXRhX3BjYSRzZGV2KSAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCkgJT4lIAogIG11dGF0ZShyb3duYW1lID0gcGFyc2VfbnVtYmVyKHJvd25hbWUpLCAKICAgICAgICAgdG90YWxWYXIgPSBzdW0oc3RhdGVfZGF0YV9wY2Ekc2Rldl4yKSwgCiAgICAgICAgIHB2ZSA9IDEwMCAqIHNkXjIgLyB0b3RhbFZhciwgCiAgICAgICAgIGN1c3VtID0gY3Vtc3VtKHB2ZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByb3duYW1lLCB5ID0gY3VzdW0pKSArIAogIGdlb21fbGluZSgpCmBgYAoKYGBge3J9CnBjYV9kYXRhIDwtIHN0YXRlX2RhdGFfcGNhJHggJT4lIAogIGRhdGEuZnJhbWUoKSAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCkgJT4lIAogIG11dGF0ZSh5ZWFyID0gc3RyX2V4dHJhY3Qocm93bmFtZSwgJ1xcZCsnKSAlPiUgYXMubnVtZXJpYygpLCAKICAgICAgICAgcm93bmFtZSA9IGdzdWIoJ1xcZHs0fScsICcnLCByb3duYW1lKSkKCnBjYV9kYXRhICU+JSAKICBnZ3Bsb3QoYWVzKHggPSAtUEMxLCB5ID0gLVBDMiwgY29sb3VyID0geWVhciAlPiUgYXMuZmFjdG9yKCkpKSArIAogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3duYW1lKSwgc2l6ZSA9IDMpCmBgYAoKYGBge3J9CiMgYXZlcmFnZWQgdmFsdWVzLCBwZXIgeWVhcgphZ2dyZWdhdGUocGNhX2RhdGEsIGJ5ID0gbGlzdChwY2FfZGF0YSRyb3duYW1lKSwgRlVOID0gbWVhbikgJT4lIAogIGdncGxvdChhZXMoeCA9IC1QQzEsIHkgPSAtUEMyKSkgKyAKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gR3JvdXAuMSksIHNpemUgPSAzKQpgYGAKCmBgYHtyfQpwY2FfZGF0YV9hbHQgPC0gYWdncmVnYXRlKHBjYV9kYXRhLCBieSA9IGxpc3QocGNhX2RhdGEkcm93bmFtZSksIEZVTiA9IG1lYW4pCnJvd25hbWVzKHBjYV9kYXRhX2FsdCkgPC0gcGNhX2RhdGFfYWx0JEdyb3VwLjEKcGNhX2RhdGFfYWx0IDwtIHBjYV9kYXRhX2FsdFssIDM6MTddCnBjYV9kYXRhX2FsdCAlPiUgCiAgZGlzdCgpICU+JSAKICBoY2x1c3QoKSAlPiUgCiAgcGxvdChjZXggPSAwLjgpCmBgYAoKYGBge3IgZmlnLndpZHRoID0gMTYsIGZpZy5oZWlnaHQgPSA2fQpwY2FfZGF0YTIgPC0gc3RhdGVfZGF0YV9wY2EkeCAlPiUgCiAgZGF0YS5mcmFtZSgpICU+JSAKICByb3duYW1lc190b19jb2x1bW4oKSAKcGNhX2RhdGEyICU+JSAKICBkaXN0KCkgJT4lIAogIGhjbHVzdCgpICU+JSAKICBwbG90KGNleCA9IDAuOCwgbGFiZWxzID0gcGNhX2RhdGEyJHJvd25hbWUpCmBgYAoKYGBge3J9CiMgdmlzdWFsaXphdGlvbgpkZiA8LSBhZ2dyZWdhdGUoc3RhdGVfcG92ZXJ0eV9yYXRlIH4gc3RhdGUsIGRhdGEgPSBzdGF0ZV9kYXRhLCBtZWFuKQpkZiA8LSBmaWx0ZXIoZGYsIAogICAgICAgICAgICAgc3RhdGUgIT0gIkRDIikgCm15Y29sb3JzX1RydWUgPC0gYnJld2VyLnBhbCg5LCAiR25CdSIpCnN0YXRlcyA8LSB0b2xvd2VyKHJvd25hbWVzKFVTQXJyZXN0cykpCm1hcF81MFMgPC0gbWFwX2RhdGEoInN0YXRlIikKCmdncGxvdChkYXRhID0gZGYsCiAgICAgICBhZXMoZmlsbCA9IHN0YXRlX3BvdmVydHlfcmF0ZSkpICsKICBsYWJzKHggPSAiTG9uZ2l0dWRlIiwgeSA9ICJMYXRpdHVkZSIsIHRpdGxlID0gIkF2ZXJhZ2UgUG92ZXJ0eSBSYXRlIGluIFN0YXRlcyIpICsKICBnZW9tX21hcChhZXMobWFwX2lkID0gc3RhdGVzKSwgbWFwID0gbWFwXzUwUykgKwogIGV4cGFuZF9saW1pdHMoeCA9IG1hcF81MFMkbG9uZywgeSA9IG1hcF81MFMkbGF0KSArCiAgdGhlbWVfYncoKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiUG92ZXJ0eSBSYXRlIiwgY29sb3VycyA9IG15Y29sb3JzX1RydWUsCiAgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAiZ3JleSIpIApgYGAKCmBgYHtyfQojIGNoYW5nZSB0d28tbGV0dGVyIGFiYnJldmlhdGlvbiB0byBmdWxsIHN0YXRlIG5hbWUgZm9yIG1lcmdpbmcKYWJicjJzdGF0ZSA8LSBmdW5jdGlvbihhYmJyKXsKICBhYiAgICA8LSB0b2xvd2VyKGMoIkFMIiwKICAgICAgICAgICAgICJBSyIsICJBWiIsICJLUyIsICJVVCIsICJDTyIsICJDVCIsCiAgICAgICAgICAgICAiREUiLCAiRkwiLCAiR0EiLCAiSEkiLCAiSUQiLCAiSUwiLAogICAgICAgICAgICAgIklOIiwgIklBIiwgIkFSIiwgIktZIiwgIkxBIiwgIk1FIiwKICAgICAgICAgICAgICJNRCIsICJNQSIsICJNSSIsICJNTiIsICJNUyIsICJNTyIsCiAgICAgICAgICAgICAiTVQiLCAiTkUiLCAiTlYiLCAiTkgiLCAiTkoiLCAiTk0iLAogICAgICAgICAgICAgIk5ZIiwgIk5DIiwgIk5EIiwgIk9IIiwgIk9LIiwgIk9SIiwKICAgICAgICAgICAgICJQQSIsICJSSSIsICJTQyIsICJTRCIsICJUTiIsICJUWCIsCiAgICAgICAgICAgICAiQ0EiLCAiVlQiLCAiVkEiLCAiV0EiLCAiV1YiLCAiV0kiLAogICAgICAgICAgICAgIldZIiwgIkRDIikpCiAgc3QgICAgPC0gYygiQWxhYmFtYSIsCiAgICAgICAgICAgICAiQWxhc2thIiwgIkFyaXpvbmEiLCAiS2Fuc2FzIiwKICAgICAgICAgICAgICJVdGFoIiwgIkNvbG9yYWRvIiwgIkNvbm5lY3RpY3V0IiwKICAgICAgICAgICAgICJEZWxhd2FyZSIsICJGbG9yaWRhIiwgIkdlb3JnaWEiLAogICAgICAgICAgICAgIkhhd2FpaSIsICJJZGFobyIsICJJbGxpbm9pcyIsCiAgICAgICAgICAgICAiSW5kaWFuYSIsICJJb3dhIiwgIkFya2Fuc2FzIiwKICAgICAgICAgICAgICJLZW50dWNreSIsICJMb3Vpc2lhbmEiLCAiTWFpbmUiLAogICAgICAgICAgICAgIk1hcnlsYW5kIiwgIk1hc3NhY2h1c2V0dHMiLCAiTWljaGlnYW4iLAogICAgICAgICAgICAgIk1pbm5lc290YSIsICJNaXNzaXNzaXBwaSIsICJNaXNzb3VyaSIsCiAgICAgICAgICAgICAiTW9udGFuYSIsICJOZWJyYXNrYSIsICJOZXZhZGEiLAogICAgICAgICAgICAgIk5ldyBIYW1wc2hpcmUiLCAiTmV3IEplcnNleSIsICJOZXcgTWV4aWNvIiwKICAgICAgICAgICAgICJOZXcgWW9yayIsICJOb3J0aCBDYXJvbGluYSIsICJOb3J0aCBEYWtvdGEiLAogICAgICAgICAgICAgIk9oaW8iLCAiT2tsYWhvbWEiLCAiT3JlZ29uIiwKICAgICAgICAgICAgICJQZW5uc3lsdmFuaWEiLCAiUmhvZGUgSXNsYW5kIiwgIlNvdXRoIENhcm9saW5hIiwKICAgICAgICAgICAgICJTb3V0aCBEYWtvdGEiLCAiVGVubmVzc2VlIiwgIlRleGFzIiwKICAgICAgICAgICAgICJDYWxpZm9ybmlhIiwgIlZlcm1vbnQiLCAiVmlyZ2luaWEiLAogICAgICAgICAgICAgIldhc2hpbmd0b24iLCAiV2VzdCBWaXJnaW5pYSIsICJXaXNjb25zaW4iLAogICAgICAgICAgICAgIld5b21pbmciLCAiRGlzdHJpY3Qgb2YgQ29sdW1iaWEiKQogIHN0W21hdGNoKHRvbG93ZXIoYWJiciksIGFiKV0KfQoKIyB2aXN1YWxpemF0aW9uCgojIGZpeGVkIG1hcAptZXJnZShtYXBfZGF0YSgic3RhdGUiKSwgCiAgICAgICAgICAgICAgICAgICAgICBhZ2dyZWdhdGUodmFyIH4gc3RhdGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBmaWx0ZXIoc3RhdGVfZGF0YSwgY291bnR5c3RhdCA9PSAicG92ZXJ0eV9yYXRlIikgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KHllYXIsIHN0YXRlLCB2YXIpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXF1ZSgpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGVU4gPSBtZWFuKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShzdGF0ZSA9IGFiYnIyc3RhdGUoc3RhdGUpICU+JSB0b2xvd2VyKCkpLCAKICAgICAgICAgICAgICAgICAgICAgIGJ5LnggPSAncmVnaW9uJywgYnkueSA9ICdzdGF0ZScpICU+JSAKICBnZ3Bsb3QoKSArIAogIGdlb21fcG9seWdvbihhZXMobG9uZywgbGF0LCBncm91cCA9IGdyb3VwLCBmaWxsID0gdmFyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzID0gbXljb2xvcnNfVHJ1ZSwgdHJhbnMgPSAnbG9nJykgKyAKICB0aGVtZV9idygpICsgCiAgbGFicyh4ID0gIkxvbmdpdHVkZSIsIHkgPSAiTGF0aXR1ZGUiLCB0aXRsZSA9ICJWYXJpYW5jZSBvZiBQb3ZlcnR5IFJhdGUgaW4gQ291bnRpZXMsIFBlciBTdGF0ZSIpCmBgYAoKYGBge3J9CiMgdmlzdWFsaXphdGlvbgoKbWVyZ2UobWFwX2RhdGEoInN0YXRlIiksIAogICAgICAgICAgICAgICAgICAgICAgYWdncmVnYXRlKHZhciB+IHN0YXRlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZmlsdGVyKHN0YXRlX2RhdGEsIGNvdW50eXN0YXQgPT0gInBvcF9kZW5zIikgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KHllYXIsIHN0YXRlLCB2YXIpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXF1ZSgpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGVU4gPSBtZWFuKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShzdGF0ZSA9IGFiYnIyc3RhdGUoc3RhdGUpICU+JSB0b2xvd2VyKCkpLCAKICAgICAgICAgICAgICAgICAgICAgIGJ5LnggPSAncmVnaW9uJywgYnkueSA9ICdzdGF0ZScpICU+JSAKICBnZ3Bsb3QoKSArIAogIGdlb21fcG9seWdvbihhZXMobG9uZywgbGF0LCBncm91cCA9IGdyb3VwLCBmaWxsID0gdmFyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzID0gbXljb2xvcnNfVHJ1ZSwgdHJhbnMgPSAnbG9nJykgKyAKICB0aGVtZV9idygpICsgCiAgbGFicyh4ID0gIkxvbmdpdHVkZSIsIHkgPSAiTGF0aXR1ZGUiLCB0aXRsZSA9ICJWYXJpYW5jZSBvZiBQb3B1bGF0aW9uIERlbnNpdHkgaW4gQ291bnRpZXMsIFBlciBTdGF0ZSIpCmBgYAoKYGBge3IgZmlnLndpZHRoID0gMTYsIGZpZy5oZWlnaHQgPSA2fQphZ2dyZWdhdGUoc3RhdGVfcGNyaW1lX3JhdGUgfiBzdGF0ZSwgZGF0YSA9IHN0YXRlX2RhdGEsIG1lYW4pICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdGF0ZSwgCiAgICAgICAgICAgICB5ID0gc3RhdGVfcGNyaW1lX3JhdGUsIAogICAgICAgICAgICAgY29sb3VyID0gc3RhdGUsIAogICAgICAgICAgICAgZ3JvdXAgPSBzdGF0ZSkpICsKICBnZW9tX2xhYmVsKGFlcyhsYWJlbCA9IHN0YXRlKSwgY2hlY2tfb3ZlcmxhcCA9IFRSVUUpKwogIGxhYnMoeCA9ICJTdGF0ZSIsIAogICAgICAgeSA9ICJBdmVyYWdlIFN0YXRlIFByb3BlcnR5IENyaW1lIFJhdGUgUGVyIHN0YXRlIChpbmNsdWRpbmcgREMpIiwgCiAgICAgICB0aXRsZSA9ICJBdmVyYWdlIFN0YXRlIFByb3BlcnR5IENyaW1lIFJhdGUgUGVyIHN0YXRlIChpbmNsdWRpbmcgREMpIikKYGBgCgpgYGB7cn0KZGZfRmFybV9Db3VudGllcyA8LSBtZXJnZShhZ2dyZWdhdGUoc3RhdGVfcF9mYXJtX2luY29tZSB+IHN0YXRlLCBkYXRhID0gc3RhdGVfZGF0YSwgbWVhbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZShuX2NvdW50aWVzIH4gc3RhdGUsIGRhdGEgPSBzdGF0ZV9kYXRhLCBtZWFuKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCdzdGF0ZScpKQpyb3duYW1lcyhkZl9GYXJtX0NvdW50aWVzKSA8LSBkZl9GYXJtX0NvdW50aWVzJHN0YXRlCgpzZXQuc2VlZCgxMDApCmZpdCA8LSBrbWVhbnMoZGZfRmFybV9Db3VudGllc1ssIDI6M10sIDUpCmNsdXNwbG90KGRmX0Zhcm1fQ291bnRpZXMsIAogICAgICAgICBmaXQkY2x1c3RlciwgCiAgICAgICAgIGNvbG9yID0gVFJVRSwgCiAgICAgICAgIHNoYWRlID0gVFJVRSwgCiAgICAgICAgIGxhYmVscyA9IDIsIAogICAgICAgICBsaW5lcyA9IDAsCiAgICAgICAgIGNleCA9IDAuNzUpCmBgYAoKYGBge3J9CmRmX0Zhcm1fUG92ZXJ0eSA8LSBtZXJnZShhZ2dyZWdhdGUoc3RhdGVfcF9mYXJtX2luY29tZSB+IHN0YXRlLCBkYXRhID0gc3RhdGVfZGF0YSwgbWVhbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgYWdncmVnYXRlKHN0YXRlX3BvdmVydHlfcmF0ZSB+IHN0YXRlLCBkYXRhID0gc3RhdGVfZGF0YSwgbWVhbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCdzdGF0ZScpKQpyb3duYW1lcyhkZl9GYXJtX1BvdmVydHkpIDwtIGRmX0Zhcm1fUG92ZXJ0eSRzdGF0ZQoKc2V0LnNlZWQoMTAwKQpmaXQyIDwtIGttZWFucyhkZl9GYXJtX1BvdmVydHlbLCAyOjNdLCA1KQpjbHVzcGxvdChkZl9GYXJtX1BvdmVydHksIAogICAgICAgICBmaXQyJGNsdXN0ZXIsIAogICAgICAgICBjb2xvciA9IFRSVUUsIAogICAgICAgICBzaGFkZSA9IFRSVUUsIAogICAgICAgICBsYWJlbHMgPSAyLCAKICAgICAgICAgbGluZXMgPSAwLAogICAgICAgICBjZXggPSAwLjc1KQpgYGAKCmBgYHtyfQpteUNsdXN0ZXIgPC0gbWFrZUNsdXN0ZXIoZGV0ZWN0Q29yZXMoKSAtIDEsIHR5cGUgPSAiRk9SSyIpCgpzeXN0ZW0udGltZSh7CiAgbG0xIDwtIGxtKHN0YXRlX3ZjcmltZV9yYXRlIH4gc3RhdGUgKyB5ZWFyICsgdmFyLCAKICAgICBkYXRhID0gc3RhdGVfZGF0YSAlPiUgZmlsdGVyKGNvdW50eXN0YXQgPT0gJ3BvdmVydHlfcmF0ZScpKSAlPiUgCiAgICBtc3VtbWFyeSgpCiAgbG0yIDwtIGxtKHN0YXRlX3ZjcmltZV9yYXRlIH4gc3RhdGUgKyB5ZWFyICsgdmFyLCAKICAgICAgICAgICAgZGF0YSA9IHN0YXRlX2RhdGEgJT4lIGZpbHRlcihjb3VudHlzdGF0ID09ICdwb3BfZGVucycpKSAlPiUgCiAgICBtc3VtbWFyeSgpCiAgbG0zIDwtIGxtKHN0YXRlX3ZjcmltZV9yYXRlIH4gc3RhdGUgKyB5ZWFyICsgbWVhbiwgCiAgICAgICAgICAgIGRhdGEgPSBzdGF0ZV9kYXRhICU+JSBmaWx0ZXIoY291bnR5c3RhdCA9PSAncF9mYXJtX2luY29tZScpKSAlPiUgCiAgICBtc3VtbWFyeSgpCiAgbG00IDwtIGxtKHN0YXRlX3ZjcmltZV9yYXRlIH4gc3RhdGUgKyB5ZWFyICsgdmFyLCAKICAgICAgICAgICAgZGF0YSA9IHN0YXRlX2RhdGEgJT4lIGZpbHRlcihjb3VudHlzdGF0ID09ICdlbXBsX3JhdGUnKSkgJT4lIAogICAgbXN1bW1hcnkoKQogIGxtNSA8LSBsbShzdGF0ZV92Y3JpbWVfcmF0ZSB+IHN0YXRlICsgeWVhciArIG1lYW4sIAogICAgICAgICAgICBkYXRhID0gc3RhdGVfZGF0YSAlPiUgZmlsdGVyKGNvdW50eXN0YXQgPT0gJ2luY29tZScpKSAlPiUgCiAgICBtc3VtbWFyeSgpCn0pCgpsbTEKbG0yCmxtMwpsbTQKbG01CgpzdG9wQ2x1c3RlcihteUNsdXN0ZXIpCmBgYA==